package cn.xshi.actuator.util;
import cn.xshi.actuator.jvm.server.*;
import cn.xshi.actuator.vo.SystemInfoDTO;
import cn.xshi.common.util.GetClientIp;
import cn.xshi.common.util.NumberUtil;
import lombok.Data;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

/**
 * @Desc 服务器相关信息
 * @Author 邓纯杰
 * @CreateTime 2013-10-05 17:15:42
 */
@Data
public class ServerUtil {

    /**
     *
     * @throws Exception
     */
    public SystemInfoDTO getSystemInfo(){

        SystemInfo systemInfo = new SystemInfo();

        HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();

        CpuInfo cpuInfo = setCpuInfo(hardwareAbstractionLayer.getProcessor());

        MemInfo memInfo = setMemInfo(hardwareAbstractionLayer.getMemory());

        SysInfo sysInfo = setSysInfo();

        JvmInfo jvmInfo = setJvmInfo();

        List<SysFileInfo> sysFileInfos = setSysFiles(systemInfo.getOperatingSystem());

        return new SystemInfoDTO(cpuInfo,memInfo,sysInfo,jvmInfo,sysFileInfos);
    }

    /**
     * 设置CPU信息
     * @param processor
     */
    private CpuInfo setCpuInfo(CentralProcessor processor) {
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        Util.sleep(1000);
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
        long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
        long softIrq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
        long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
        long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
        long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
        long ioWait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
        long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + ioWait + irq + softIrq + steal;
        CpuInfo cpuInfo = new CpuInfo();//CPU信息
        cpuInfo.setCpuNum(processor.getLogicalProcessorCount());
        cpuInfo.setTotal(totalCpu);
        cpuInfo.setSys(cSys);
        cpuInfo.setUsed(user);
        cpuInfo.setWait(ioWait);
        cpuInfo.setFree(idle);
        return cpuInfo;
    }

    /**
     * 设置内存信息
     * @param memory
     */
    private MemInfo setMemInfo(GlobalMemory memory) {
        MemInfo memInfo = new MemInfo();//內存相关信息
        memInfo.setTotal(memory.getTotal());
        memInfo.setUsed(memory.getTotal() - memory.getAvailable());
        memInfo.setFree(memory.getAvailable());
        return memInfo;
    }

    /**
     * 设置服务器信息
     */
    private SysInfo setSysInfo() {
        Properties properties = System.getProperties();
        SysInfo sysInfo = new SysInfo();//服务器相关信息
        sysInfo.setComputerName(GetClientIp.getLocalName());
        sysInfo.setIp(GetClientIp.getLocalIp());
        sysInfo.setOsName(properties.getProperty("os.name"));
        sysInfo.setOsArch(properties.getProperty("os.arch"));
        sysInfo.setUserDir(properties.getProperty("user.dir"));
        return sysInfo;
    }

    /**
     * 设置Java虚拟机
     */
    private JvmInfo setJvmInfo(){
        Properties properties = System.getProperties();
        JvmInfo jvmInfo = new JvmInfo();//JVM相关信息
        jvmInfo.setTotal(Runtime.getRuntime().totalMemory());
        jvmInfo.setMax(Runtime.getRuntime().maxMemory());
        jvmInfo.setFree(Runtime.getRuntime().freeMemory());
        jvmInfo.setVersion(properties.getProperty("java.version"));
        jvmInfo.setHome(properties.getProperty("java.home"));
        return jvmInfo;
    }

    /**
     * 设置磁盘信息
     * @param operatingSystem
     */
    private List<SysFileInfo> setSysFiles(OperatingSystem operatingSystem) {
        FileSystem fileSystem = operatingSystem.getFileSystem();
        OSFileStore[] fsArray = fileSystem.getFileStores();
        List<SysFileInfo> sysFileInfos = new LinkedList<SysFileInfo>();//磁盘相关信息
        for (OSFileStore fs : fsArray) {
            long free = fs.getUsableSpace();
            long total = fs.getTotalSpace();
            long used = total - free;
            SysFileInfo sysFileInfo = new SysFileInfo();
            sysFileInfo.setDirName(fs.getMount());//盘符路径
            sysFileInfo.setSysTypeName(fs.getType());//盘符类型
            sysFileInfo.setFileTypeName(fs.getName());//文件类型名称
            sysFileInfo.setTotal(ActuatorSDKUtil.computeFileSize(total));
            sysFileInfo.setFree(ActuatorSDKUtil.computeFileSize(free));
            sysFileInfo.setUsed(ActuatorSDKUtil.computeFileSize(used));
            sysFileInfo.setUsage(NumberUtil.mul(NumberUtil.div(used, total, 4), 100));
            sysFileInfos.add(sysFileInfo);
        }
        return sysFileInfos;
    }
}
